package capricornus.res
{
	import capricornus.events.ResLoaderEvent;
	import capricornus.net.loader.ResLoader;
	import capricornus.utils.pool.ResDelayFreeController;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	public class ImageManager extends EventDispatcher
	{
		private var _dictCounter:Dictionary;
		private var _dictBitmapData:Dictionary;
		private var _dictBitmap:Dictionary;
		
		private var _dictLoading:Dictionary;
		
		private static var _ins:ImageManager=null;
		
		private var _delayFreeController:ResDelayFreeController;
		
		public function ImageManager()
		{
			super(null);
			init();
		}
		
		private function init():void
		{
			_dictCounter = new Dictionary();
			_dictBitmapData = new Dictionary();
			_dictBitmap = new Dictionary();
			
			_dictLoading = new Dictionary();
			
			_delayFreeController = new ResDelayFreeController( free );
		}
		
		public static function get instance():ImageManager
		{
			if( null==_ins )
			{
				_ins = new ImageManager();
			}
			return _ins;
		}
		
		public function getBitmapData( url:String ):BitmapData
		{
			return _dictBitmapData[url];
		}
		
		public function getImage( url:String ):Bitmap
		{
			var bd:BitmapData = _dictBitmapData[url];
			var bt:Bitmap = new Bitmap( bd );
			
			if( _dictCounter[url] )
			{
				_dictCounter[url] = _dictCounter[url] + 1;
			}
			else
			{
				_dictCounter[url] = 1;
			}
			
			_delayFreeController.stopFree( url );
			
			if( bd==null )
			{
				var arr:Array = _dictBitmap[url];
				if( !arr )
				{
					arr = new Array();
					_dictBitmap[url] = arr;
				}
				arr.push( bt );
				
				if( _dictLoading[url]==null )
				{
					var sl:ResLoader = new ResLoader();
					sl.addEventListener( ResLoaderEvent.COMPLETE, onLoadedComplete );
					sl.load( url );
					
					_dictLoading[url] = sl;
				}
			}
			
			return bt;
		}
		
		public function releaseImage( url:String ):void
		{
			if( _dictCounter[url] )
			{
				var counter:int = _dictCounter[url];
				counter--;
				_dictCounter[url] = counter;
				if( counter <= 0 )
				{
					_delayFreeController.free( url );
					var sl:ResLoader;
					if( (sl=_dictLoading[url]) != null )
					{
						sl.removeEventListener( ResLoaderEvent.COMPLETE, onLoadedComplete );
						sl.destroy();
						
						delete _dictLoading[url];
					}
				}
			}
		}
		
		private function free( url:String ):void
		{
			var obj:Object;
			if( (obj=_dictCounter[url])==null ) return;
			
			if( int(obj) <= 0 )
			{
				delete _dictCounter[url];
				var bd:BitmapData = _dictBitmapData[url];
				if( bd ) bd.dispose();
				delete _dictBitmapData[url];
				var arr:Array = _dictBitmap[url];
				if( arr )
				{
					while( arr.length > 0 )
					{
						var bt:Bitmap = arr.pop() as Bitmap;
						bt.bitmapData = null;
					}
					arr.length = 0;
				}
				delete _dictBitmap[url];
			}
		}
		
		private function onLoadedComplete( e:ResLoaderEvent ):void
		{
			var sl:ResLoader = e.currentTarget as ResLoader;
			sl.removeEventListener( ResLoaderEvent.COMPLETE, onLoadedComplete );
			
			var bitmap:Bitmap = e.data as Bitmap;
			var url:String = sl.url;
			
			sl.destroy();
			delete _dictLoading[url];
			
			if( bitmap && _dictCounter[url] )
			{
				var bitmapData:BitmapData = bitmap.bitmapData;
				bitmap.bitmapData = null;
				_dictBitmapData[url] = bitmapData;
				
				var arr:Array = _dictBitmap[url];
				if( arr )
				{
					while( arr.length > 0 )
					{
						var bt:Bitmap = arr.pop() as Bitmap;
						bt.bitmapData = bitmapData;
					}
					delete _dictBitmap[url];
				}
				
				dispatchEvent( new Event( url ) );
			}
		}
	}
}





